package anaydis.animation.sort.gui;

import anaydis.animation.core.AnimationController;
import anaydis.animation.sort.SortAnimation;
import com.sun.istack.internal.NotNull;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;

public class AnimationDisplayArea
        extends JComponent
        implements AnimationController
{
    private SortAnimation sortAnimation;

    private boolean running;

    private final Main main;
    private final Dimension minimum;
    private final SortToolBar toolBar;
    private final JComboBox animations;


    AnimationDisplayArea(@NotNull final Main main, @NotNull final SortToolBar toolBar,
                         @NotNull final JComboBox animations, final int panels)
    {
        this.main = main;
        this.toolBar = toolBar;
        this.minimum = new Dimension(700, 500 / panels);
        this.animations = animations;
        setMinimumSize(minimum);
        setBorder(BorderFactory.createLoweredBevelBorder());
        setBackground(Color.WHITE);
        setOpaque(true);
        toolBar.setControler(this);
    }

    public Dimension getPreferredSize()
    {
        return minimum;
    }

    protected void paintComponent(@NotNull final Graphics graphics)
    {
        graphics.setColor(Color.WHITE);

        final int width = getWidth();
        final int height = getHeight();

        graphics.fillRect(0, 0, width, height);

        if (sortAnimation != null)
        {
            sortAnimation.paintArray((Graphics2D) graphics.create(FRAME_SPACE, FRAME_SPACE, width - 2 * FRAME_SPACE,
                    height - 2 * FRAME_SPACE));
        }
    }

    @NotNull public Dimension getDisplayAreaSize()
    {
        return getSize();
    }


    public void end()
    {
        running = false;

        if (!main.anyRunning()) {
            toolBar.enableControls(running);
        }

        animations.setEnabled(!running);
    }

    public void pause()
    {
        toolBar.pause();
    }

    public void itemStateChanged(ItemEvent e)
    {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            initAnimation();
        }
    }

    public void actionPerformed(ActionEvent e)
    {
        String cmd = e.getActionCommand();
        if (cmd.equals(AnimationController.RUN_COMMAND)) {
            if (running && sortAnimation != null) {
                sortAnimation.pause();
            }
            else {
                running = true;
                initAnimation();
                sortAnimation.setSpeed(toolBar.getSlider().getValue());
                sortAnimation.start();
            }
        }
        else if (cmd.equals(AnimationController.STOP_COMMAND))
        {
            if(running) {
                sortAnimation.pause();
            }

            running = false;
            sortAnimation.doStop();
            initAnimation();
        }

        if (main.anyRunning() == running) {
            toolBar.enableControls(running);
            animations.setEnabled(!running);
        }
    }

    void initAnimation()
    {
        sortAnimation = getSortAlgorithm();
        sortAnimation.init(this, (getSize().width - 2 * FRAME_SPACE - 4) / 16);
        sortAnimation.setData(toolBar.getData());
    }

    public SortAnimation getSortAlgorithm()
    {
        return (SortAnimation) animations.getSelectedItem();
    }


    public void stateChanged(ChangeEvent e)
    {
        JSlider slider = toolBar.getSlider();
        if (sortAnimation != null && e.getSource() == slider) {
            sortAnimation.setSpeed(slider.getValue());
        }
    }

    public boolean isRunning()
    {
        return running;
    }

    private static final int FRAME_SPACE = 5;
}